package com.happyhome.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import com.happyhome.constants.AppConstant;
import com.happyhome.datamodel.Image;
import com.happyhome.datamodel.Opinion;
import com.happyhome.services.ImageService;
import com.happyhome.services.OpinionService;

@Controller
@RequestMapping("/admin/opinions")
public class OpinionsController {
	
	private static final Logger log = LoggerFactory.getLogger(OpinionsController.class);
	
	@Autowired
	private OpinionService opinionService;
	
	@Autowired
	private ImageService imageService;
	
	@Autowired
	private ServletContext context;
	
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ModelAndView list() {
		return new ModelAndView("/admin/opinion/list");
	}
	
	@RequestMapping(value = "/new", method = RequestMethod.GET)
	public ModelAndView newOpinion() {
		ModelAndView model = new ModelAndView("/admin/opinion/new");
		return model;
	}
	
	private Image persistImage(MultipartHttpServletRequest request){
		Iterator<String> itr = request.getFileNames();
        MultipartFile mpf;
        
        mpf = request.getFile(itr.next());
        
        String newFilenameBase = UUID.randomUUID().toString();
        String originalFileExtension = mpf.getOriginalFilename().substring(mpf.getOriginalFilename().lastIndexOf("."));
        String newFilename = newFilenameBase + originalFileExtension;
        
        String filename = "/WEB-INF" ;
		String pathname = context.getRealPath(filename);
		
		File dir = new File(pathname + File.separator + "images");
		
		if(!dir.exists()){
			dir.mkdirs();
		}
		
        String contentType = mpf.getContentType();
        
        File newFile = new File(dir.getAbsolutePath() + File.separator + newFilename);
        try {
            mpf.transferTo(newFile);
            
            Image image = new Image();
            image.setName(mpf.getOriginalFilename());
            image.setNewFilename(newFilename);
            image.setContentType(contentType);
            image.setSize(mpf.getSize());
            image.setDateCreated(new Date());
            image.setLastUpdated(new Date());
            return image;
        } catch(IOException e) {
        	log.error("Could not upload file " + mpf.getOriginalFilename(), e);
            return null;
        }
	}
	
	/* form new House submit form */
	@RequestMapping(value = "/newSubmit", method = RequestMethod.POST)
	public @ResponseBody String newOpinionSubmit(MultipartHttpServletRequest request, HttpServletResponse response){
		Map<String, String[]> multiParameters = request.getParameterMap();
	    Opinion opinion = setValueForOpinion(null, multiParameters);
	    try{
	    	Image image = persistImage(request);
	    	image = imageService.merge(image);
            opinion.setImage(image);
            opinion = opinionService.merge(opinion);
            return opinion.getId().toString();
        } catch(Exception ex) {
            return "fail";
        }
	}
	
	private Opinion setValueForOpinion(Opinion opinion, Map<String, String[]> multiParameters){
		if(opinion == null){
			opinion = new Opinion();
		}
		
		String[] content = multiParameters.get(AppConstant.CONTENT);
		if(content != null ){
			opinion.setContent(content[0]);
			multiParameters.remove(AppConstant.CONTENT);
		}
		
		String[] author = multiParameters.get(AppConstant.AUTHOR);
		if(author != null ){
			opinion.setAuthor(author[0]);
			multiParameters.remove(AppConstant.AUTHOR);
		}
		
		// set status to true
		opinion.setStatus(Boolean.valueOf("true"));
		opinion.setDateCreated(new Date());
		
		return opinion;
	}
	
	/* edit room */
 	@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
 	public ModelAndView editOpinion(@PathVariable Long id){
 		Opinion opinion = opinionService.findById(id);
 		// set url for opinion
 		if(opinion.getImage() != null){
 			opinion.setUrl("/" + AppConstant.APP_URL + "/admin/picture/" + opinion.getImage().getId());
 		}
 		ModelAndView model = new ModelAndView("/admin/opinion/edit");
		model.addObject("opinion", opinion);
		return model;
 	}
 	
 	/* delete new */
 	@RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    public @ResponseBody String deleteNews(@PathVariable Long id) {
 		Opinion opinion = opinionService.findById(id);
 		opinion.setStatus(Boolean.valueOf("false"));
 		opinionService.merge(opinion);
        return "success";
    }
 	
 	@RequestMapping(value = "/editSubmit", method = RequestMethod.POST)
 	public @ResponseBody String editSubmit(MultipartHttpServletRequest request, HttpServletResponse response){
		Map<String, String[]> multiParameters = request.getParameterMap();
	    Opinion opinionTarget = opinionService.findById(Long.parseLong(multiParameters.get("id")[0]));
	    setValueForOpinion(opinionTarget, multiParameters);
	    	// if opinion has image, delete before insert
	    	Image image = null;
	    	try{
	    		image = persistImage(request);
	    	}catch(Exception ex){
	    		log.debug(ex.getMessage());
	    		opinionTarget = opinionService.merge(opinionTarget);
	            return opinionTarget.getId().toString();
	    	}
	    	if(image != null){
		    	try{
		    		if(opinionTarget.getImage() != null){
			    		Image imageTarget = imageService.getImageById(opinionTarget.getImage().getId());
				        String pathname = context.getRealPath(AppConstant.IMAGE_LOCATION);
				        File imageFile = new File(pathname + "/" + imageTarget.getNewFilename());
				        imageFile.delete();
				        File thumbnailFile = new File(pathname + "/" + imageTarget.getThumbnailFilename());
				        thumbnailFile.delete();
		    		}
			        image = imageService.merge(image);
			    	opinionTarget.setImage(image);
			    	opinionTarget = opinionService.merge(opinionTarget);
					return opinionTarget.getId().toString();
		    	}catch(Exception ex){
		    		log.debug(ex.getMessage());
		    	}
	    	}
	    	return "fail";
	}
	
 	/**
 	 * get All data to return list rooms
 	 * @return
 	 */
 	@RequestMapping(value = "/getDataOpinions", method = RequestMethod.GET)
    public @ResponseBody List<Opinion> getDataNews() {
    	List<Opinion> listOpinions = opinionService.getAllOpinions();
	    return listOpinions;
    }
 	
    @RequestMapping(value = "/setDisplayCavas", method = RequestMethod.POST)
    public @ResponseBody String setDisplayCavas(HttpServletRequest request) {
    	List<Long> listLongId = new ArrayList<Long>();
    	Map<String, String[]> multiParameters = request.getParameterMap();
    	String[] listId = multiParameters.get("listId");
    	if(listId != null){
    		String[] listIdValue = listId[0].split(",");
    		try{
    			for(int i = 0; i < listIdValue.length; i++){
    				Long idNews = Long.parseLong(listIdValue[i]);
    				listLongId.add(idNews);
    			}
				opinionService.setDisplayCavas(listLongId);
				return "success";
    		}catch(NumberFormatException exception){
    			return "fail";
    		}
    	}
    	return "success";
    }
}
